Skip to content

feat: Redirects improvements#5619

Merged
kof merged 16 commits intomainfrom
redirects.staging
Feb 19, 2026
Merged

feat: Redirects improvements#5619
kof merged 16 commits intomainfrom
redirects.staging

Conversation

@kof
Copy link
Member

@kof kof commented Feb 18, 2026

• Import from any platform (CSV, JSON, htaccess, Netlify)
• Loop detection so you can't break your site
• Wildcard patterns: /old/* → /new/*
• Non-latin characters support

Show a warning banner when a redirect path matches the current page path, indicating the redirect will override access to the page.

Changes:

  • Add PanelBanner component with warning variant to page settings
  • Implement findMatchingRedirect utility to detect redirect conflicts
  • Show contextual warning with link to Redirects settings section
  • Add comprehensive tests for redirect conflict detection

Code quality:

  • Replace 'return undefined' with 'return' per style guide
  • Use 'return null' for React components returning nothing

kof added 16 commits February 18, 2026 19:48
Show a warning banner when a redirect path matches the current page path,
indicating the redirect will override access to the page.

Changes:
- Add PanelBanner component with warning variant to page settings
- Implement findMatchingRedirect utility to detect redirect conflicts
- Show contextual warning with link to Redirects settings section
- Add comprehensive tests for redirect conflict detection

Code quality:
- Replace 'return undefined' with 'return' per style guide
- Use 'return null' for React components returning nothing
…ccess

- Add parseRedirects() function with auto-format detection
- Support CSV (Shopify, HubSpot, WordPress, generic)
- Support JSON (Vercel, Next.js, generic array)
- Support Netlify _redirects format
- Support Apache .htaccess Redirect directives
- Use papaparse for robust CSV parsing
- Normalize status codes (307->302, 308->301)
- Strip trailing slashes from source paths
- Skip unsupported patterns (wildcards, placeholders, conditions)
- Add comprehensive test suite (107 tests)
- Add fixture files for all formats
- Add README with documentation and UI plan
- Add ImportRedirectsDialog component with file upload and paste support
- Implement parseRedirects() with auto-detection for CSV, JSON, Netlify _redirects, and Apache .htaccess formats
- Support popular exports: Shopify, HubSpot, Vercel, Next.js
- Add preview step showing parsed redirects, unsupported lines, and duplicates
- Add merge mode options: add to existing or replace all
- Move Toaster to builder.tsx for proper z-index layering
- Use 'old'/'new' field names to match SDK PageRedirect schema
- Include 107 comprehensive tests for parser
- Move description text into info tooltip for cleaner UI
- Update OldPagePath schema to allow Unicode/UTF-8 characters
  (Chinese, Japanese, Korean, Cyrillic, Arabic, Hebrew, Thai, Greek, etc.)
- Only disallow truly problematic URL characters (spaces, <, >, ", {, }, |, \, ^, `, [, ])
- Add comprehensive tests for non-Latin character support in paths
- Update existing tests to use new error message format
Verify that the URLPattern-based router correctly handles:
- Chinese (Simplified & Traditional)
- Japanese (Hiragana, Katakana, Kanji)
- Korean (Hangul)
- Cyrillic, Arabic, Hebrew, Greek
- European diacritics (über, café, niño)
- Dynamic segments capturing non-Latin characters
- Wildcard patterns with non-Latin paths
- URL-encoded to literal decoding
Verify generateRemixRoute correctly handles:
- Chinese (关于我们, 产品/手机)
- Japanese (日本語, ブログ/記事)
- Korean (한국어)
- Cyrillic (привет, блог/статья)
- European diacritics (über-uns, café)
- Mixed Latin and non-Latin paths

Note: React Router handles URL decoding at runtime to match
encoded URLs against Unicode filenames.
Creates a shared test data module (redirect-path-test-data.ts) that defines:
- VALID_REDIRECT_PATHS: categorized valid paths (basic, patterns, non-Latin, etc.)
- INVALID_REDIRECT_PATHS: categorized invalid paths (spaces, unsafe chars, etc.)
- VALID_URLPATTERN_PATHS: paths suitable for URLPattern testing
- STATIC_PATHS: non-pattern paths for route generation testing

This ensures all three layers are tested with the same path data:
1. OldPagePath schema validation (SDK) - 67 tests
2. URLPattern matching (builder) - 174 tests total
3. Route generation (react-sdk) - 113 tests total

When a new path type needs support, add it to redirect-path-test-data.ts
and all layers will automatically be tested for consistency.
These test utilities validate router paths in general, not just redirects:
- Pages, redirects, and any routable URLs all use the same path rules
- URLPattern matching is used for all page routing in the builder
- Route generation is used for all pages on published sites

Renamed:
- redirect-path-test-data.ts → router-path-test-data.ts
- redirect-paths.test.ts → router-paths.test.ts
- VALID_REDIRECT_PATHS → VALID_ROUTER_PATHS
- INVALID_REDIRECT_PATHS → INVALID_ROUTER_PATHS
- @webstudio-is/sdk/redirect-paths.test → @webstudio-is/sdk/router-paths.test
…er tests

Added comprehensive test cases discovered from React Router test suite:

- Dynamic params with dashes: /courses/:foo-bar
- Multiple consecutive optionals: /nested/:one?/:two?/:three?/:four?
- Intercalated optionals: /nested/one?/two/three?
- New mixedOptionals category: /nested/:one?/two/:three?, /one?/:two?/three/:four/*
- Extended file extensions: .tar.gz, .min.js patterns
- Sitemap patterns: /sitemap/:lang.xml

Sources:
- matchPath-test.tsx
- path-matching-test.tsx
- generatePath-test.tsx
- special-characters-test.tsx
- Move search and action buttons to separate row below Redirects label
- Add onAbort handler to clear search field
- Fix ProjectNewRedirectPath schema to reject empty strings
- Fix delete button by adding index parameter to map callback
- Add test coverage for empty path validation
- Use node: protocol prefix for fs and path imports
- Replace dynamic imports with top-level imports using readFileSync
- Change statusPart from let to const
- Add eslint-disable comment for control regex in pages.ts
When clicking outside the combobox, don't reset the typed value.
Only update when onChange receives an actual value, not undefined.
Move from project-settings/redirect-parsers to shared/redirects
so it can be used by both project settings and page settings.
- Add wouldCreateLoop() and detectLoopsInBatch() utilities
- Export LOOP_ERROR constant for consistent error messaging
- Integrate loop detection in section-redirects, import-dialog, and page-settings
- Move redirect-parsers to shared/redirects/ directory
- Remove duplicate redirect-parsers folder
@kof kof merged commit 9f497a3 into main Feb 19, 2026
32 of 34 checks passed
@kof kof deleted the redirects.staging branch February 19, 2026 10:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant